/**
 * @description user 控制层
 * @author LI
 */

const { getAccountInfo, createAccount } = require('../services/account')
const {
  createUser,
  getGoodListByTypeName,
  getGoodsInfoListById,
  getGoodsPhotoInfoById,
  getGoodsProductsInfoById,
  getGoodsDecoratitemsInfoById,
  linkUserDeductionByLink,
  linkAccount,
  timeOutIP,
  getSMSCodeByPhone,
  updateUserPwdByAccount,
  getQQUserInfoByCode,
  sendSMS
} = require('../services/user')
const doCrypto = require('../utils/cryp')
const { getPhoneCodeExpired } = require('../cache/phoneCode')
const { ReturnResult } = require('../model/ResultModel')

/**
 * 注册用户信息，用户提交信息保存
 * @param {string} userName 姓名
 * @param {string} phone 手机号
 * @param {number} area 面积
 * @param {string} address 地址
 * @param {string} remark 备注/要求
 */
async function register({ userName, phone, area, address, remark }) {
  try {
    // 接下来交给服务层，
    // 此处可以返回新增等数据库之后的信息 const user = 信息，最后返回这个 user 就是新增数据库的信息
    await createUser({
      userName,
      phone,
      area,
      address,
      remark
    })
    return new ReturnResult(0, null, true, "添加成功")
  } catch (e) {
    console.error(e.message, e.stack)
    return new ReturnResult(0, null, false, "添加失败，请重试")
  }
}
/**
 * 用户提交信息，给手机发送短信提示
 * @param {string} phone 手机号
 */
async function sendBoosSMS(phone) {
  try {
    // 接下来交给服务层，
    // 此处可以返回新增等数据库之后的信息 const user = 信息，最后返回这个 user 就是新增数据库的信息
    await sendSMS(phone)
    return new ReturnResult(0, null, true, "发送成功")
  } catch (e) {
    console.error(e.message, e.stack)
    return new ReturnResult(0, null, false, "发送失败，请重试")
  }
}

/**
 * 获取分类下面的商品列表
 * @param {string} typeName 分类名称，通过名称查询全部商品
 * @param {number} page 第几页
 * @param {number} limit 条数
 */
async function getGoodTypeList({ typeName, page, limit }) {
  try {
    // 接下来交给服务层，
    // 此处可以返回新增等数据库之后的信息 const user = 信息，最后返回这个 user 就是新增数据库的信息
    const result =  await getGoodListByTypeName({
      typeName,
      page,
      limit
    })

    return new ReturnResult(result.rows.length, result.rows, true, "操作成功")
  } catch (e) {
    console.error(e.message, e.stack)
    return new ReturnResult(0, null, false, "失败，请重试")
  }
}

/**
 * 获取商品信息列表
 * @param {number} id 商品 id 用来获取产品装修列表
 */
async function getGoodsInfoList(id) {
  try {
    const result = await getGoodsInfoListById(id)

    return new ReturnResult(0, result, true, "操作成功")
  } catch (e) {
    return new ReturnResult(0, null, false, e.message)
  }
}

/**
 * 获取商品图片信息列表
 * @param {number} id 商品 id 用来获取商品图片列表
 */
async function getGoodsPhotoInfo(id) {
  try {
    const result = await getGoodsPhotoInfoById(id)

    return new ReturnResult(result.count, result.rows, true, "操作成功")
  } catch (e) {
    return new ReturnResult(0, null, false, e.message)
  }
}

/**
 * 获取商品产品信息列表
 * @param {number} id 商品 id 用来获取商品产品列表
 */
async function getGoodsProductsInfo(id) {
  try {
    const result = await getGoodsProductsInfoById(id)

    return new ReturnResult(result.count, result.rows, true, "操作成功")
  } catch (e) {
    return new ReturnResult(0, null, false, e.message)
  }
}

/**
 * 获取商品装修信息列表
 * @param {number} id 商品 id 用来获取商品装修列表
 */
async function getGoodsDecoratitemsInfo(id) {
  try {
    const result = await getGoodsDecoratitemsInfoById(id)

    return new ReturnResult(result.count, result.rows, true, "操作成功")
  } catch (e) {
    return new ReturnResult(0, null, false, e.message)
  }
}

/**
 * 通过链接进行店铺相应的扣款
 * @param {string} companyAddress 用户点击的链接
 * @param {string} accessIp 用户客户端 ip
 */
async function linkUserDeduction(companyAddress, accessIp) {
  try {
    // 判断链接是否存在于账号表中，判断 ip 合法性是否超过 24 小时
    let resultAccount = await linkAccount(companyAddress)
    if (!resultAccount) {
      return new ReturnResult(0, null, true, "无链接用户")
    }
    if ((resultAccount.balance - resultAccount.adPrice) <= 0) {
      return new ReturnResult(0, null, false, "此商品链接不可查看")
    }
    const linkUserId = parseInt(resultAccount.id)
    const deductionPrice = Number(resultAccount.adPrice)
    const balance = Number(resultAccount.balance)
    const resultIP = await timeOutIP({ linkUserId, deductionPrice, accessIp })
    if (!resultIP) {
      return new ReturnResult(0, null, true, "24小时内已经查看此商品")
    }

    const result = await linkUserDeductionByLink(linkUserId, deductionPrice, balance)

    return new ReturnResult(0, null, true, "操作成功")
  } catch (e) {
    return new ReturnResult(0, null, false, e.message)
  }
}

/**
 * 获取短信验证码
 * @param phone 手机号账号
 */
async function getSMSCode(phone) {
  try {
    // 获取账号信息
    const accountInfo = await getAccountInfo(phone)
    const result = await getSMSCodeByPhone(phone)
    return new ReturnResult(0, result, true, "获取验证码成功")
  } catch (e) {
    console.error(e.message, e.stack)
    return new ReturnResult(0, null, false, e.message)
  }
}

/**
 * 添加链接用户注册
 * @param {string} account 手机号账号
 * @param {string} pwd 密码
 * @param {number} code 验证码
 * @param {number} typecode 链接用户类型
 * @param {string} typeLevel 二级类型
 */
async function linkRegister({ account, pwd, code, typecode, typeLevel}) {
  try {
    // 获取账号信息
    const accountInfo = await getAccountInfo(account)
    let getCodeExpired = await getPhoneCodeExpired(account, String(code))
    if (accountInfo) {
      // 账号已存在
      return new ReturnResult(0, null, false, "账号已存在")
    }
    // 验证码目前不需要
    // if (!getCodeExpired) {
    //   return new ReturnResult(0, null, false, "验证码不存在")
    // }
    // if (code !== Number(getCodeExpired)) {
    //   return new ReturnResult(0, null, false, "验证码输入错误")
    // }
    // 接下来交给服务层，
    // 此处可以返回新增等数据库之后的信息 const user = 信息，最后返回这个 user 就是新增数据库的信息
    const result = await createAccount({ account, pwd, typecode, typeLevel })
    return new ReturnResult(0, null, true, "添加成功")
  } catch (e) {
    console.error(e.message, e.stack)
    return new ReturnResult(0, null, false, "添加失败，请重试")
  }
}

/**
 * 链接用户重置密码
 * @param {string} account 手机号账号
 * @param {string} pwd 密码
 * @param {number} code 验证码
 */
async function updateUserPwd({ account, code, pwd }) {
  try {
    let getCodeExpired = await getPhoneCodeExpired(account, String(code))
    if (!getCodeExpired) {
      return new ReturnResult(0, null, false, "验证码不存在")
    }
    if (code !== Number(getCodeExpired)) {
      return new ReturnResult(0, null, false, "验证码输入错误")
    }
    // 接下来交给服务层，
    // 此处可以返回新增等数据库之后的信息 const user = 信息，最后返回这个 user 就是新增数据库的信息
    const result = await updateUserPwdByAccount({
      account,
      pwd: doCrypto(pwd)
    })
    return new ReturnResult(0, null, result, "重置成功")
  } catch (e) {
    console.error(e.message, e.stack)
    return new ReturnResult(0, null, false, "重置失败，请重试")
  }
}

/**
 * 获取 qq 用户账号信息 openId
 * @param {string} code qq code码
 */
async function getQQUserInfo(code) {
  try {
    const result = await getQQUserInfoByCode(code)
    return new ReturnResult(0, result, true, "获取成功")
  } catch (e) {
    console.error(e.message, e.stack)
    return new ReturnResult(0, null, false, "失败，请重试")
  }
}

module.exports = {
  register,
  getGoodTypeList,
  getGoodsInfoList,
  getGoodsPhotoInfo,
  getGoodsProductsInfo,
  getGoodsDecoratitemsInfo,
  linkUserDeduction,
  linkRegister,
  getSMSCode,
  updateUserPwd,
  getQQUserInfo,
  sendBoosSMS
}
